/*
 * Copyright (c) 2025 Huawei Device, Inc. Ltd. and <马弓手>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APPLICATION_H
#define APPLICATION_H

#include <mutex>
#include <rawfile/raw_file_manager.h>
#include <string>
#include <map>
#include <web/arkweb_scheme_handler.h>
#include <web/arkweb_type.h>
using namespace  std;

struct SDateTime
{
     int   m_nDate;  // time, format:HHmmSS
     int   m_nTime;  // date, format:YYYYMMDD
     SDateTime():m_nDate(0), m_nTime(0) {}
     SDateTime(int nDate, int nTime) {m_nDate = nDate; m_nTime = nTime;}
     bool operator ==(const SDateTime& arg) {if(m_nDate == arg.m_nDate && m_nTime == arg.m_nTime) return true; return false;}
     SDateTime(const SDateTime& arg){m_nDate = arg.m_nDate; m_nTime = arg.m_nTime;}
     SDateTime& operator =(const SDateTime& arg) {if(this == &arg) return *this; m_nDate = arg.m_nDate; m_nTime = arg.m_nTime; return *this;}
     bool operator >=(const SDateTime& arg) const{
            if(m_nDate > arg.m_nDate)
                    return true;
            else if(m_nDate == arg.m_nDate && m_nTime >= arg.m_nTime)
                    return true;
            return false;
     }
     bool operator <=(const SDateTime& arg) const {
            if(m_nDate < arg.m_nDate)
                    return true;
            else if(m_nDate == arg.m_nDate && m_nTime <= arg.m_nTime)
                    return true;
            return false;
     }
     bool operator <(const SDateTime& arg) const {
            if(m_nDate < arg.m_nDate)
                    return true;
            else if(m_nDate == arg.m_nDate && m_nTime < arg.m_nTime)
                    return true;
            return false;
     }
     bool operator >(const SDateTime& arg) const {
            if(m_nDate > arg.m_nDate)
                    return true;
            else if(m_nDate == arg.m_nDate && m_nTime > arg.m_nTime)
                    return true;
            return false;
     }
     bool operator !=(const SDateTime& arg) const {
             if(m_nDate == arg.m_nDate && m_nTime == arg.m_nTime)
                    return false;
            return true;
     }

     bool operator ==(const SDateTime& arg) const {
            return (m_nDate == arg.m_nDate && m_nTime == arg.m_nTime);
     }
};

/**
 * @brief Global object for the Cordova C++ side.
 */
class Application {
    static std::mutex s_mutex;
    static map<string, map<string, string> > s_mapWebTagToResource;
    static map<uintptr_t, string> s_mapSchemeHandlerToWebTag;
    static map<string, vector<string> > s_mapWebTagToCustomHttpHeaders;
    static map<string, bool> s_mapWebTagToIsAllowCredentials;
    static map<string, void*> s_mapFunctionRefresh;
public:
    /**cache directory of webview*/
    static string g_strCachePath;
    /**database directory*/
    static string g_databaseDir;
    /**Web controller, used for controller-related APIs. All frontend WebViews can use it.*/
    static ArkWeb_ControllerAPI *g_controller;
    /**web component, used for component-related APIs. All frontend WebViews can use it.*/
    static ArkWeb_ComponentAPI *g_component;
    /**Current app's resource manager object, used for handling rawfile files.*/
    static NativeResourceManager *g_resourceManager;
    /**web cookie, used for cookie-related APIs. All frontend WebViews can use it.*/
    static ArkWeb_CookieManagerAPI *g_cookieManage;
    /**Connection pool object for obtaining socket or TLS/SSL communication.*/
    static void* g_connPoolManage;
    /**Virtual domain name. This domain is used to load rawfile files and sandbox files.*/
    static string g_strTmpUrl;
    /**Cross-origin request thread pool object, used for handling web requests.*/
    static void* g_httpGroupRunner;
    /**Paged memory management object.*/
    static void* g_memPool;
    /**Execution environment for calling ArkTS functions from the C++ side.*/
    static void* g_env;
    /**cordova view Controller*/
    static void* g_cordovaViewController;
    /**Push messages received before Cordova is initialized.*/
    static string g_strPushInfoBeforeInit;
    /**Background proxy push notifications. Messages saved before Cordova is initialized (currently unused).*/
    static string g_strNotificationBeforeInit;
    /**custom scheme*/
    static vector<string> g_vecCustomSchemes;
    /**WebTags of all WebViews opened by the frontend.*/
    static vector<string> g_vecWebTag;
    /**All domains using Cordova proxy for HTTP protocol handling.*/
    static vector<string> g_vecProtocolUrl;
    /**Safe function pointer for asynchronous calls from C++ to ArkTS.*/
    static napi_threadsafe_function g_tsfn;
    /**
     * Hot update directory. After setting the hot update directory in the plugin,
     * the WebView will load updated resource files from the specified directory.
     */
    static string g_strHotCodeUpdateDirectory;
    /**
     * @brief Saves the schemeHandler and webTag to s_mapSchemeHandlerToWebTag.
     * @param pSchemeHandler Scheme handler pointer.
     * @param strWebTag Web tag string.
     */
    static void putSchemeHandlerWebTag(const void* pSchemeHandler, const string& strWebTag);
    /**
     * @brief Saves resources to be replaced during HTTP requests.
     * @param strWebTag Web tag string.
     * @param strSrc Source url
     * @param strObj Target url
     */
    static void pushResource(const string& strWebTag, const string& strSrc, const string& strObj);
    /**
     * @brief Retrieves the target resource to replace based on the source resource.
     * @param pSchemeHandler Scheme handler pointer.
     * @param strSrc Source url
     * @return Returns the target resource if a replacement exists; otherwise returns the source resource.
     */
    static string getResourceObj(const void* pSchemeHandler, const string& strSrc);
    /**
     * @brief Clears the resources marked for replacement (executed after the page finishes loading).
     * @param strWebTag Web tag string.
     */
    static void clearResource(const string& strWebTag);
    /**
     * @brief Adds custom HTTP headers (only keys, no values) to s_mapWebTagToCustomHttpHeaders.
     * @param strWebTag Web tag string.
     * @param strCustomerHttpHeaders
     */
    static void addCustomHttpHeaders(const string& strWebTag, const string& strCustomerHttpHeaders);
    /**
     * @brief Gets custom HTTP headers.
     * @param pSchemeHandler Scheme handler pointer.
     * @return Returns HTTP headers, with multiple headers separated by ",".
     */
    static string getCustomHttpHeaders(const void* pSchemeHandler);
    /**
     * @brief Sets withCredentials.
     * @param strWebTag  Web tag string.
     * @param isAllowCredentials true or false
     */
    static void addIsAllowCredentials(const string& strWebTag, const bool isAllowCredentials);
    /**
     * Gets withCredentials.
     * @param pSchemeHandler
     * @return true or false
     */
    static bool getIsAllowCredentials(const void* pSchemeHandler);
    /**
     * @brief remove scheme handler
     * @param strWebTag Web tag string.
     */
    static void removeSchemeHandlerWebTag(const string & strWebTag);
    /**
     * @brief Checks if the scheme handler is valid.
     * @param pSchemeHandler scheme handler
     * @return true if valid, false if invalid.
     */
    static bool isValidSchemeHandler(const void* pSchemeHandler);
    /**
     * @brief Checks if the web tag is valid.
     * @param strWebTag Web tag string
     * @return true if valid, false if invalid.
     */
    static bool isValidWebTag(const string& strWebTag);
    /**
     * @brief Adds the reference address of an ArkTS function.
     * @param strWebTag web tag string
     * @param pFunctionRefresh Function reference address.
     */
    static void addFunctionRefresh(const string& strWebTag, void* pFunctionRefresh);
    /**
     * @brief Retrieves the ArkTS function reference based on the web tag.
     * @param strWebTag web tag string
     * @return Function reference address.
     */
    static void* getFunctionRefresh(const string& strWebTag);
    /**
     * @brief Deletes the reference address of an ArkTS function.
     * @param strWebTag web tag string
     */
    static void delFunctionRefresh(const string& strWebTag);
    /**
     * @brief 
     * @return strWebTag web tag string
     */
    static string getFirstWebTag();
    
    /**
     * @brief
     * @return vector for web tag string
     */
    static vector<string> getAllWebTag();
};
#endif